﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Net;
using System.IO;

namespace Notepad_X
{
    public enum DownloadTypes { General, Update, Autoclose,List, Toolbar, Translation, Plugin, IconPack, Highlighter, UpdateCheck };
    /// <summary>
    /// To start an download use :
    /// Download dll = new Download(url,path,type);
    //  dll.ShowDialog();
    /// </summary>
    public partial class Download : Form
    {
        /// <summary>
        /// Use General as default, or Autoclose to close the window the the download is completed
        /// </summary>
        public DownloadTypes file_type;

        public delegate void DownloadCompletedHandler(object sender,DownloadCompleted e);
        public event DownloadCompletedHandler DownloadCompletedEvent;

        //public string file_type; // general ,list, toolbar , translation , plugin , iconpack , highlighter
        public string file_url;
        public string file_path;

        /// <summary>
        /// Creates a Download window to download a file over the internet
        /// </summary>
        /// <param name="url">The url of the file</param>
        /// <param name="path">The path of the file to be saved</param>
        /// <param name="type">The DownloadTypes type variable ,Use General & Autoclose as default</param>
        public Download(string url, string path, DownloadTypes type)
        {
            file_type = type;
            file_url = url;
            file_path = path;
            InitializeComponent();
            info.Text = "Downloading " + Path.GetFileName(path);
        }

        private void Download_Load(object sender, EventArgs e)
        {
            //If language set, because it can be used without the main form loaded
            if (Main.app_language != null)
            {
                this.Text = Main.app_language[Notepad_X.Classes.Strings.Download];
            }

            // Check if internet connection is available
            bool ok = true;
            if (!Notepad_X.Classes.Functions.ConnectionAvailable("http://notepad-x.sourceforge.net"))
            {
                if (MessageBox.Show("No internet connection found \n do you want to cancel the download ?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    ok = false;
                    this.Close();
                }
            }
            if (ok) { DownloadWorker.RunWorkerAsync(); }
        }

        private void cancel_Click(object sender, EventArgs e)
        {
            DownloadWorker.CancelAsync();
            progress.Value = 0;
            status.Text = "Download Stopped";
            this.Close();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {           
                // first, we need to get the exact size (in bytes) of the file we are downloading
                Uri url = new Uri(file_url);

                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
                //request.Referer = "notepad-x";
                System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
                response.Close();

                // gets the size of the file in bytes
                Int64 iSize = response.ContentLength;

                // keeps track of the total bytes downloaded so we can update the progress bar
                Int64 iRunningByteTotal = 0;

                // use the webclient object to download the file
                using (System.Net.WebClient client = new System.Net.WebClient())
                {
                    // open the file at the remote URL for reading
                    using (System.IO.Stream streamRemote = client.OpenRead(new Uri(file_url)))
                    {
                        // using the FileStream object, we can write the downloaded bytes to the file system
                        using (Stream streamLocal = new FileStream(file_path, FileMode.Create, FileAccess.Write, FileShare.None))
                        {

                            // loop the stream and get the file into the byte buffer
                            int iByteSize = 0;

                            // this will prevent any error if we cant get the size
                            if (iSize == -1) { iSize = 8; }

                            byte[] byteBuffer = new byte[iSize];
                            while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
                            {

                                // write the bytes to the file system at the file path specified
                                streamLocal.Write(byteBuffer, 0, iByteSize);

                                iRunningByteTotal += iByteSize;

                                // calculate the progress out of a base "100"
                                double dIndex = (double)(iRunningByteTotal);
                                double dTotal = (double)byteBuffer.Length;
                                double dProgressPercentage = (dIndex / dTotal);
                                int iProgressPercentage = (int)(dProgressPercentage * 100);

                                // this will prevent any errors
                                if (iProgressPercentage > 100){iProgressPercentage = 100;}

                                // update the progress bar
                                DownloadWorker.ReportProgress(iProgressPercentage);

                            }
                            // clean up the file stream
                            streamLocal.Close();
                        }
                        // close the connection to the remote server
                        streamRemote.Close();
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }   

        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progress.Value = e.ProgressPercentage;
            prog_l.Text = e.ProgressPercentage.ToString() +"/100";
        }

        private void DownloaderCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            DownloadCompleted dllCompleted = new DownloadCompleted(file_url, file_path, file_type);

            try
            {
                DownloadCompletedEvent(this, dllCompleted);
            }
            catch (Exception) { }

            if (file_type == DownloadTypes.Autoclose)
            {
                this.Close();
            }else if(file_type == DownloadTypes.General)
            {
                info.Text = "Download Compelete";
                cancel.Text = "Close";
            }else{
                this.Close();
            }

        }
    }
    /// <summary>
    /// DownloadCompleted Event 
    /// </summary>
    public class DownloadCompleted : EventArgs
    {
        public DownloadCompleted(String Url,String Path,DownloadTypes Type)
        {
            FileUrl = Url;
            FilePath = Path;
            DownloadType = Type;
        }

        public DownloadTypes DownloadType;
        public String FilePath;
        public String FileUrl;
    }
}
